/*
 * @Description: 微信获取授权
 * @Autor: HuiSir<273250950@qq.com>
 * @Date: 2021-04-19 16:42:55
 * @LastEditTime: 2021-04-26 14:37:22
 */
import { getUserInfo, wxLogin } from "../api/login"
let { globalData } = getApp()

const doAuth = async (redirectPage) => {
    try {

        let code = await getCode()

        let userInfo = await getUserInfo(code)
        if (userInfo) {
            globalData.userInfo = userInfo
            globalData.isLogin = 1
            wx.redirectTo({ url: redirectPage })
        }

    } catch (err) {

        globalData.userInfo = null
        globalData.isLogin = 0

        wx.showModal({
            title: '错误提示',
            content: err,
            showCancel: false,
            confirmText: '重连',
            success (res) {
                if (res.confirm) {
                    doAuth() //递归重载
                }
            }
        })

    }
}

const doWxLogin = async (redirect, wxUserInfo) => {
    try {

        let code = await getCode()

        wxUserInfo.code = code

        console.log("wxUserInfo", wxUserInfo)

        // let userInfo = await wxLogin(wxUserInfo)

        // if (userInfo) {
        //     globalData.userInfo = userInfo
        //     globalData.isLogin = 1
        //     wx.redirectTo({ url: redirect })
        // }

    } catch (err) {

        globalData.userInfo = null
        globalData.isLogin = 0

        wx.showModal({
            title: '错误提示',
            content: err,
            showCancel: false,
            confirmText: '重新登录',
            success (res) {
                if (res.confirm) {
                    doWxLogin() //递归重载
                }
            }
        })

    }
}

function getCode () {
    return new Promise((resolve, reject) => {
        wx.getSetting({
            success: res => {
                if (res.authSetting['scope.userInfo']) {
                    wx.login({
                        success: ({ code, errMsg }) => {
                            if (code) {
                                resolve(code)
                            } else {
                                reject('登录失败：' + errMsg)
                            }
                        },
                        fail: () => {
                            reject("登录失败：未知错误！")
                        }
                    })
                } else {
                    reject("登录失败：暂未获得登录授权！")
                }
            },
            fail: () => {
                reject("登录失败：授权验证失败！")
            }
        })
    })
}

export {
    doAuth,
    doWxLogin
}

// 发送 code 到后台换取 openId (unionid、session_key) -> 通过openId拿到用户信息
// 若user表中openId存在（说明先前已登陆过）：
// 1.后台可以维护一个登录状态，自定义登录是否失效
//      也可以在前台通过session_key有效期判断是否失效，需要前台执行wx.checkSession校验 session_key 是否有效（若有效的话需要再次请求后台将openId传给后台来拿用户信息），
//      也可以不设状态，登录永远有效（但这样的话若用户修改了昵称、地址、头像等不会更新user表）。
// 2.若登录状态暂未失效，将用户所有信息返回前台，前台将登录状态重置为已登录
// 3.若登录状态失效，则告知前台，前台保持未登录状态，若须登录再手动登录
// 4.手动登录流程：(1)通过wx.getUserProfile授权拉取微信用户信息，通过接口将code和个人信息（昵称、地址、头像等）传到后台
// 				(2)后台获取openId,通过openId找到用户，更新用户信息（昵称、地址、头像等）
// 				(3)后台将用户所有信息返回前台
// 				(4)前台将登录状态重置为已登录
// 若user表中openId不存在：
// 1.后台不做任何操作
// 2.后台将结果通过此接口告知前台，前台将登录结果保持为未登录
// 3.如须登录，则前台通过点击按钮，再次通过wx.login获取code（不缓存code因为code会失效）,通过wx.getUserProfile授权拉取微信用户信息，通过接口将code和个人信息（昵称、地址、头像等）传到后台
// 4.后台新增一条user存表，然后将登录状态置为已登录，返回前台登录成功结果
// 5.前台将登录结果置为已登录
// 非个人开发者可以通过按钮获取微信绑定的手机号，所以在登录时后可以将获取的手机号和微信个人信息一并传给后台存表
// 若没有获取手机号的权限，如需使用手机号，则需要通过手机验证码形式，将手机号和code一并传给后台
// 若使用手机号登录必须要获取微信用户信息（昵称、地址、头像等），则在登录时需要wx.getUserProfile同时获取信息一并传与后台
// 也可以直接通过普通的注册和账号登录来进行登录，或使用手机号验证码登录（直接绑了手机号，下次通过手机号登录）。
// 总之，看具体的业务需求


// 会话密钥 session_key 有效性
// 开发者如果遇到因为 session_key 不正确而校验签名失败或解密失败，请关注下面几个与 session_key 有关的注意事项。
// wx.login 调用时，用户的 session_key 可能会被更新而致使旧 session_key 失效（刷新机制存在最短周期，如果同一个用户短时间内多次调用 wx.login，并非每次调用都导致 session_key 刷新）。开发者应该在明确需要重新登录时才调用 wx.login，及时通过 auth.code2Session 接口更新服务器存储的 session_key。
// 微信不会把 session_key 的有效期告知开发者。我们会根据用户使用小程序的行为对 session_key 进行续期。用户越频繁使用小程序，session_key 有效期越长。
// 开发者在 session_key 失效时，可以通过重新执行登录流程获取有效的 session_key。使用接口 wx.checkSession可以校验 session_key 是否有效，从而避免小程序反复执行登录流程。
// 当开发者在实现自定义登录态时，可以考虑以 session_key 有效期作为自身登录态有效期，也可以实现自定义的时效性策略。